import { observable, action } from "mobx";
import * as API from '../../apis/mindMap';
import {message} from 'antd';
import * as _ from 'lodash';
// import { WeaLocaleProvider } from 'ecCom';
// const getLabel = WeaLocaleProvider.getLabel;
import $ from "jquery";
import Actions from "../card/actions";
import { decodeMultiLang } from "../../cubeUtil";
import { isFromProtal } from "../../util/cubeUtil";
import myWindow from '../../util';

const getLength = (str) => {
    let realLength = 0, len = str.length, charCode = -1;
    for (let i = 0; i < len; i++) {
        charCode = str.charCodeAt(i);
        if (charCode >= 0 && charCode <= 128) realLength += 1;
        else realLength += 2;
    }
    return realLength;
};
const getSubStr = (str, start, length) => {
    let rt:any = [], currentLength = 0, len = str.length, charCode = -1;
    for (let i = 0; i < len; i++) {
        charCode = str.charCodeAt(i);
        if (charCode >= 0 && charCode <= 128) {
            currentLength++;
        } else {
            currentLength += 2;
        }
        if (currentLength > start && currentLength <= length) {
            rt.push(str.charAt(i));
        }
    }
    return rt.join('');
}
const getShortStr = (ele, data, w = 100,fontSize = 12) => {
    const tempDiv = document.createElement('div');
    tempDiv.style.display = "inline-block";
    tempDiv.style.fontSize = fontSize+"px";
    tempDiv.innerHTML = data;
    document.body.appendChild(tempDiv);
    const le = tempDiv.offsetWidth;
    document.body.removeChild(tempDiv);
    const oneCharLen = Math.ceil(le / getLength(data));
    const length = Math.floor(w / oneCharLen);
    const datalength = data ? getLength(data) : 0;
    if (length >= datalength) {
        return data;
    }
    return getSubStr(data, 0, length - 3) + '...';
}

export default class MindMapStore {
    @observable rootDatas: any ={};
    nodes:any;  //所有的节点
    links:any;  //所有的连线
    gNode:any;  //所有节点组
    gLink:any;  //所有连线组
    root:any;

    @observable loading: boolean = false;
    @observable mindMapId: string;
    @observable rootId: string;
    @observable level: string;
    @observable isshowroot;
    @observable windowTitle = '';
    otherParam;

    width =window.document.body.offsetWidth-4;
    height =window.document.body.offsetHeight-4;
    isFirstInit=true;  //是否第一次渲染图形

    nodeWidth=220;
    nodeHeight=80;

    //右键相关
    @observable rightMenuTop=0;
    @observable rightMenuLeft=0;
    @observable rightMenuVisible=false;

    //右键相关
    Actions = new Actions(this);

    nodeStyle;

    @action
    clearAll = () => {
        //清空所有子节点
        const d3: any = window['d3'];
        const mindMapContainer = d3.select('#mindMapContainer');
        if(mindMapContainer){
            mindMapContainer.selectAll("svg > *").remove();
        }
        this.rootId="";
    }

    @action
    init = (mindMapId?) => {
        let { query } = myWindow.weaHistory.getCurrentLocation();        

        const d3: any = window['d3'];
        const mindMapContainer=d3.select('#mindMapContainer').attr('width',this.width).attr('height',this.height).attr('transform',d3.zoomIdentity).append("g");
        this.gNode = mindMapContainer.append("g").attr('id','nodeGroup');
        this.gLink=mindMapContainer.append('g').attr('id','nodePath');
        this.isFirstInit=true;
        
        this.loading = true;
        if (mindMapId) {
            this.mindMapId = mindMapId;
        }
        API.getMindInfoAndNodeStyle({mindMapid:this.mindMapId,rootid:this.rootId,isold:this.otherParam.isold}).then(({ error, status,info,nodeStyle,rootid,mindMapid}) => {
            if (status == '1') {
                if(!this.isshowroot)this.isshowroot=info.isshowroot;
                if(query['level']>0){
                    this.level = query['level'];
                }else{
                    if(!this.level)this.level=info.defaultexpenddepth||0;
                    //qc#813014
                    if(this.level != info.defaultexpenddepth)this.level=info.defaultexpenddepth||0;
                }
                
                this.nodeStyle=nodeStyle;
                if(rootid)this.rootId=rootid;//rootId在只有一个节点的情况下支持只传递数据id
                this.mindMapId=mindMapid;
                this.loadData();
            } else {
                message.error(error);
                throw error;
            }
            this.loading = false;
        });
        
        d3.select('#mindMapContainer').call(d3.zoom().scaleExtent([1/10, 10]).on("zoom", ()=>{mindMapContainer.attr("transform", d3.event.transform.toString());}));
        window.focus(); 
    }

    @action
    loadData=(node?)=>{
        let type='root';//root:根节点 rootid:传rootid参数的根节点 node:点击节点加载
        let pid='';
        if(node){//分支节点
            pid=node.data.id;
            type='node';
        }else if(this.rootId&&!node){
            pid=this.rootId;
            type='rootid';
        }
        const d3: any = window['d3'];
        this.loading = true;
        API.getDatas({...this.otherParam,id:this.mindMapId,pid,type,level:this.level}).then(({ error, status,tlist,levelDatas,windowTitle }) => {
            if (status == '1') {
                if(!isFromProtal()){
                    this.windowTitle = windowTitle;
                }
                if(type!='node'&&parseInt(this.level)>0){
                    this.rootDatas=levelDatas;
                    this.rootDatas.name=this.replaceParam(decodeMultiLang(this.rootDatas.name));
                }else{
                    if(type!='node'){
                        let name='';
                        let id='';
                        let childNum=0;
                        tlist.forEach(item=>{
                            name=item['name'];
                            id=item['id'];
                            childNum=item['childNum'];
                        });
                        this.rootDatas['name']=this.replaceParam(decodeMultiLang(name));
                        this.rootDatas['id']=id;
                        this.rootDatas['childNum']=childNum;
                    }else{
                        node.data['children']=tlist;
                        node.data['_children']=tlist;
                    }
                }
                this.root = d3.hierarchy(this.rootDatas);
                this.root.descendants().forEach((d, i) => {
                    d.id = i;
                    d._children = d.children;
                });
                this.root.x0 = 0;
                this.root.y0 = 0;
                if(node){
                    this.updateNode(node);
                }else{
                    this.updateNode(this.root);
                }
            } else {
                message.error(error);
                throw error;
            }
            this.loading = false;
        });
    }

    replaceParam=(str)=>{
        if(this.otherParam){
            _.keys(this.otherParam).forEach(item=>{
                str=str.replace(new RegExp("\\$"+item+"\\$","g"),this.otherParam[item]);
            });
        }
        return str;
    }


    @action
    updateNode=(sourceNode)=>{
        const d3: any = window['d3'];
        this.nodes = this.root.descendants();
        this.links = this.root.links();
        let leftDeviation=this.nodeWidth;
        if(this.isshowroot=='0'){
            let rootid="0_0";
            if(this.rootId){
                rootid=this.rootId;
            }
            this.nodes=this.nodes.filter(e=>{
                return e.data.id==rootid?false:true;
            });
            this.links=this.links.filter(e=>{
                return e.source.data.id==rootid?false:true;
            });
            leftDeviation=this.nodeWidth*2;
        }
        const tree=d3.tree().nodeSize([this.nodeHeight+20,this.nodeWidth+80]);
        tree(this.root);//计算x及y赋予this.root

        let left = this.root;
        let right = this.root;
        this.root.eachBefore(node => {//感觉y是屏幕上的横坐标，x是纵坐标
            if (node.y < left.y) left = node;
            if (node.y > right.y) right = node;
        });
        //动画效果
        const transition = d3.select('#mindMapContainer').transition().duration(500);
        if(this.isFirstInit){
            d3.select('#mindMapContainer').attr("viewBox",(-(this.width-(right.y-left.y))/2+leftDeviation)+","+(-this.height/2)+","+this.width+","+this.height);
        }
        //节点处理
        const node=this.gNode.selectAll("g").data(this.nodes,d=>d.data.id);
        const nodeEnter = node.enter().append('g').attr("transform", d => `translate(${sourceNode.y0},${sourceNode.x0})`).on("click", d => {
            if(!d.data.childNum)return;
            d.children = d.children ? null : d._children; 
            if(d.depth>=this.level)d.data.children = d.data.children ? null : d.data._children;
            if(d.data.isloaded&&d.data.childNum!=0&&!d.children&&!d._children)d.data.isloaded=false;
            if(d.data.isloaded){
                this.updateNode(d);
            }else{
                this.loadData(d);
                d.data['isloaded']=true;
            }
        });
        this.constructNodeDom(nodeEnter);
        node.merge(nodeEnter).transition(transition).attr("transform", d =>`translate(${d.y},${d.x})`).attr("fill-opacity", 1).attr("stroke-opacity", 1);
        node.exit().transition(transition).remove().attr("transform", d => `translate(${sourceNode.y},${sourceNode.x})`).attr("fill-opacity", 0).attr("stroke-opacity", 0);
        //连线处理
        this.gLink.attr("fill", "none").attr("stroke", "#555").attr("stroke-opacity", 0.4).attr("stroke-width", 1.5);
        const link = this.gLink.selectAll("path").data(this.links,d =>d.target.data.id);
        const diagonal = d3.linkHorizontal().x(d => d.y).y(d => d.x);
        const linkEnter=link.enter().append('path').attr('d',d=>{
            const o = {x: sourceNode.x0+this.nodeHeight/2, y: sourceNode.y0};
            return diagonal({source: o, target: o});
        });
        link.merge(linkEnter).transition(transition).attr("d", d=>{
            return diagonal({source:{x:d.source.x+this.nodeHeight/2,y:d.source.y+this.nodeWidth},target:{x:d.target.x+this.nodeHeight/2,y:d.target.y}});
        });
        link.exit().transition(transition).remove().attr("d", d => {
            const o = {x: sourceNode.x+this.nodeHeight/2, y: sourceNode.y};
            return diagonal({source: o, target: o});
        });

        // Stash the old positions for transition.
        this.root.eachBefore(d => {
            d.x0 = d.x;
            d.y0 = d.y;
        });
        this.isFirstInit=false;
    }

    //获取右键按钮
    getRightContextMenu=(d)=>{
        const e:any=window.event;
        // this.loading = true;
        // API.getRightMenus({id:d.data.id}).then(({ error, status,rightMenus,urlMap,confirmMap}) => {
        //     if (status == '1') {
        //         console.log('right',rightMenus,urlMap,confirmMap);
        //         this.rightMenuLeft=e.clientX;
        //         this.rightMenuTop=e.clientY;
        //         this.rightMenuVisible=true;
        //     } else {
        //         message.error(error);
        //         throw error;
        //     }
        //     this.loading = false;
        // });

        e.preventDefault();
    }

    getFontHeight=(fontSize)=>{
        let h=0;
        if(fontSize>=10&&fontSize<=13){
            h=fontSize+4;
        }else if(fontSize>=14&&fontSize<=17){
            h=fontSize+5;
        }else if(fontSize>=18&&fontSize<=20){
            h=fontSize+6;
        }
        return h-4;
    }

    constructNodeDom=(nodeEnter)=>{
        nodeEnter.append('rect').attr('width',this.nodeWidth).attr('height',this.nodeHeight).attr('fill','#ffffff').attr('rx',5).attr('ry',5).attr('stroke-width',1).attr('stroke','rgb(216, 216, 220)').on('contextmenu',this.getRightContextMenu);
        let w=190;
        //配置过节点信息的
        _.keys(this.nodeStyle).forEach(nodeid=>{
            this.nodeStyle[nodeid].forEach(element => {
                //配置的字段等于分支节点显示字段，添加链接
                nodeEnter.data(this.nodes.filter(d=>{
                    return d.data.nodeid==nodeid&&element['fieldName']==d.data.showfield;
                }),d=>d.data.id).append("a").attr("onclick",d=>"window['cube_mindMap_titleCilck']('"+d.data.id+"')").attr('onmouseover',"this.getElementsByTagName('text')[0].setAttribute('fill','#017afd')").attr('onmouseout',"this.getElementsByTagName('text')[0].setAttribute('fill','"+element.fontColor+"')").append("text").attr("transform", d =>{
                    let positionY=element['positionY'];
                    positionY+=this.getFontHeight(element['fontSize']);
                    return `translate(${element['positionX']},${positionY})`
                }).text(d => getShortStr(this,d.data.styleFields[element['fieldName']],w-element['positionX'],element['fontSize'])).attr('style',`font-size:${element['fontSize']}px;`).attr('fill',element['fontColor']).on('contextmenu',this.getRightContextMenu).append('title').text(d => d.data.styleFields[element['fieldName']]);
                //配置的字段不等于分支节点显示字段
                nodeEnter.data(this.nodes.filter(d=>{
                    return d.data.nodeid==nodeid&&element['fieldName']!=d.data.showfield;
                }),d=>d.data.id).append("text").attr("transform", d =>{
                    let positionY=element['positionY'];
                    positionY+=this.getFontHeight(element['fontSize']);
                    return `translate(${element['positionX']},${positionY})`
                }).text(d => getShortStr(this,d.data.styleFields[element['fieldName']],w-element['positionX'],element['fontSize'])).attr('style',`font-size:${element['fontSize']}px;`).attr('fill',element['fontColor']).on('contextmenu',this.getRightContextMenu).append('title').text(d => d.data.styleFields[element['fieldName']]);
            });
        });
        //未配置过节点信息的
        let unSettingNodeEnter=nodeEnter.data(this.nodes.filter(element=>!this.nodeStyle[element.data.nodeid]),d=>d.data.id);
        unSettingNodeEnter.append("a").attr("onclick",d=>"window['cube_mindMap_titleCilck']('"+d.data.id+"')").attr('onmouseover',"this.getElementsByTagName('text')[0].setAttribute('fill','#017afd')").attr('onmouseout',"this.getElementsByTagName('text')[0].setAttribute('fill','')").
        append("text").attr("transform", d =>`translate(10,22)`).text(d => getShortStr(this,d.data.name,w,)).on('contextmenu',this.getRightContextMenu).append('title').text(d => d.data.name);
        unSettingNodeEnter.append("text").attr("transform", d =>`translate(10,62)`).text(d => d.data.modedatacreater).attr('fill','#8a8a8a').on('contextmenu',this.getRightContextMenu);
        unSettingNodeEnter.append("text").attr("transform", d =>`translate(120,62)`).text(d => d.data.modedatacreatedate).attr('fill','#8a8a8a').on('contextmenu',this.getRightContextMenu);
        
        //子节点个数
        nodeEnter.data(this.nodes.filter(d=>d.data.childNum),d=>d.data.id).append("rect").attr('width',0).attr('height',0).attr('rx',5).attr('ry',5).attr('fill','#017afd').attr("id",d=>"childNumRect"+d.data.id).attr("transform", d =>`translate(188,21)`).on('contextmenu',this.getRightContextMenu);
        nodeEnter.data(this.nodes.filter(d=>d.data.childNum),d=>d.data.id).append("text").attr("id",d=>"childNum"+d.data.id).text(d => d.data.childNum).attr('fill','white').attr("transform", d =>`translate(190,35)`).on('contextmenu',this.getRightContextMenu);
        //子节点个数，数字添加背景色
        $("rect[id^='childNumRect']").each((i,element) => {
            const numElement=$('#'+element.id.replace('childNumRect','childNum'))[0];
            const SVGRect = numElement.getBBox();
            if(SVGRect.width)element.setAttribute('width',SVGRect.width+4);
            if(SVGRect.height)element.setAttribute('height',SVGRect.height+3);
        });
    }

    titleClick=(nodeid)=>{
        this.loading = true;
        API.getNodeHref({id:this.mindMapId,pid:nodeid}).then(({ error, status,href}) => {
            if (status == '1') {
                href=decodeMultiLang(href);
                if(nodeid='0_0'){
                    href=this.replaceParam(href);
                }
                if(href)window.open(href);
            } else {
                message.error(error);
                throw error;
            }
            this.loading = false;
        });

        var e = window.event || arguments.callee.caller.arguments[0];
        e.stopPropagation(); 
    }

}
